<?php


namespace app\common\service\redis;

use think\facade\Config;
use think\cache\driver\Redis;

class PoolRedis extends Redis
{
    /**
     * @var int
     */

    protected $hash;

    /**
     * @var array
     */

    protected static $instance = [];

    /**
     * Redis constructor.
     * @param $db
     */

    private function __construct($db)

    {
        $options = Config::get('cache.stores.redis');
        $options['select'] = $db;
        $this->hash = $db;
        $this->options = array_merge($this->options, $options);

        parent::__construct();
    }

    private function __clone()
    {
    }

    /**
     * @param int $db
     * @return Redis
     */

    public static function instance()
    {
        $db = env('redis.select', 0);
        if (!isset(self::$instance[$db])) {
            self::$instance[$db] = new self($db);
        }
        return self::$instance[$db];

    }

    public function __destruct()
    {
        self::$instance[$this->hash]->close();
        unset(self::$instance[$this->hash]);
    }

    //使用scan匹配all key,非阻塞
    public static function scanAllForMatch($pattern, $cursor=null, $results=[]) {
        $redis = self::instance();
        $redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);  //设置迭代
        while ($keys = call_user_func_array(array($redis, 'scan'), array(&$cursor, $pattern, 1000))){
            $results = array_merge($results, $keys);
        }
        return array_values(array_unique($results));
    }


    //使用sscan匹配 set 集合中 all key
    public static function setScanAllForMatch($key, $pattern='*', $cursor=null, $count = 3000, $results=[]) {
        if ($cursor === "0") {
            return $results;
        }

        if ($cursor === null) {
            $cursor = "0";
        }

        $redis = self::instance();
        list($cursor, $result) = $redis->sscan($key, $cursor, $pattern, $count);

        $results = array_merge($results, $result);


        return self::setScanAllForMatch($key, $pattern, $cursor, $count, $results);

    }
}